package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"

	"gitee.com/mdgsf/HTTPUseProtoBuf"
	"github.com/golang/protobuf/proto"
)

func showHTTPData(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	log.Println("r.Method = ", r.Method)
	log.Println("r.Proto = ", r.Proto)
	log.Println("r.URL.Path = ", r.URL.Path)
	log.Println("r.URL.Scheme = ", r.URL.Scheme)
	log.Println("r.Form = ", r.Form)
	log.Println("r.Form[url_long] = ", r.Form["url_long"])
	for k, v := range r.Form {
		log.Println("key:", k)
		log.Println("val:", strings.Join(v, ""))
	}
	log.Println("r.ContentLength = ", r.ContentLength)
	body, _ := ioutil.ReadAll(r.Body)
	log.Println("r.Body = ", body)
	log.Println("r.Body = ", string(body))
	log.Println()
}

func sayhelloName(w http.ResponseWriter, r *http.Request) {
	log.Println("sayhelloName")
	showHTTPData(w, r)

	fmt.Fprintf(w, "hello astaxie!")
}

type sLogin struct {
	Username string //这些成员的变量名要用public的，也就是第一个字母大写。
	Password string
}

func jsonPostLogin(w http.ResponseWriter, r *http.Request) {
	log.Println("jsonPostLogin")
	r.ParseForm()
	log.Println("r.Method = ", r.Method)
	log.Println("r.Proto = ", r.Proto)
	log.Println("r.URL.Path = ", r.URL.Path)
	log.Println("r.URL.Scheme = ", r.URL.Scheme)
	log.Println("r.Form = ", r.Form)
	log.Println("r.Form[url_long] = ", r.Form["url_long"])
	for k, v := range r.Form {
		log.Println("key:", k)
		log.Println("val:", strings.Join(v, ""))
	}
	log.Println("r.ContentLength = ", r.ContentLength)
	body, _ := ioutil.ReadAll(r.Body)
	log.Println("r.Body = ", body)
	log.Println("r.Body = ", string(body))

	s := &sLogin{}
	err := json.Unmarshal(body, s)
	if err != nil {
		log.Fatal("json unmarshal failed")
	}
	log.Println(s.Username, s.Password)
	log.Println()

	if s.Username == "huangjian" && s.Password == "123" {
		fmt.Fprintf(w, "Login success!")
	} else {
		fmt.Fprintf(w, "Login failed!")
	}
}

func protoPostRegister(w http.ResponseWriter, r *http.Request) {
	log.Println("protoPostRegister")
	r.ParseForm()
	log.Println("r.Method = ", r.Method)
	log.Println("r.Proto = ", r.Proto)
	log.Println("r.URL.Path = ", r.URL.Path)
	log.Println("r.URL.Scheme = ", r.URL.Scheme)
	log.Println("r.Form = ", r.Form)
	log.Println("r.Form[url_long] = ", r.Form["url_long"])
	for k, v := range r.Form {
		log.Println("key:", k)
		log.Println("val:", strings.Join(v, ""))
	}
	log.Println("r.ContentLength = ", r.ContentLength)
	body, _ := ioutil.ReadAll(r.Body)
	log.Println("r.Body = ", body)
	log.Println("r.Body = ", string(body))

	reg := &HTTPUseProtoBuf.Register{}
	err := proto.Unmarshal(body, reg)
	if err != nil {
		log.Fatal("unmarshaling error:", err)
	}

	log.Println(reg)
	log.Println()

	fmt.Fprintf(w, "Register success!")
}

func protoPostArr(w http.ResponseWriter, r *http.Request) {
	log.Println("protoPostArr")
	r.ParseForm()
	log.Println("r.Method = ", r.Method)
	log.Println("r.Proto = ", r.Proto)
	log.Println("r.URL.Path = ", r.URL.Path)
	log.Println("r.URL.Scheme = ", r.URL.Scheme)
	log.Println("r.Form = ", r.Form)
	log.Println("r.Form[url_long] = ", r.Form["url_long"])
	for k, v := range r.Form {
		log.Println("key:", k)
		log.Println("val:", strings.Join(v, ""))
	}
	log.Println("r.ContentLength = ", r.ContentLength)
	body, _ := ioutil.ReadAll(r.Body)
	log.Println("r.Body = ", body)
	log.Println("r.Body = ", string(body))

	arr := &HTTPUseProtoBuf.MsgArr{}
	err := proto.Unmarshal(body, arr)
	if err != nil {
		log.Fatal("unmarshaling error:", err)
	}

	log.Println(arr)
	log.Println(arr.Money)
	log.Println()

	fmt.Fprintf(w, "Get money success!")
}

func protoPostWrap(w http.ResponseWriter, r *http.Request) {
	log.Println("protoPostWrap")
	r.ParseForm()
	log.Println("r.Method = ", r.Method)
	log.Println("r.Proto = ", r.Proto)
	log.Println("r.URL.Path = ", r.URL.Path)
	log.Println("r.URL.Scheme = ", r.URL.Scheme)
	log.Println("r.Form = ", r.Form)
	log.Println("r.Form[url_long] = ", r.Form["url_long"])
	for k, v := range r.Form {
		log.Println("key:", k)
		log.Println("val:", strings.Join(v, ""))
	}
	log.Println("r.ContentLength = ", r.ContentLength)
	body, _ := ioutil.ReadAll(r.Body)
	log.Println("r.Body = ", body)
	log.Println("r.Body = ", string(body))

	out := &HTTPUseProtoBuf.MsgOuter{}
	err := proto.Unmarshal(body, out)
	if err != nil {
		log.Fatal("unmarshaling error:", err)
	}

	log.Println(out)
	log.Println()

	fmt.Fprintf(w, "Get out in success!")
}

func protoPostCmplx(w http.ResponseWriter, r *http.Request) {
	log.Println("protoPostCmplx")
	r.ParseForm()
	log.Println("r.Method = ", r.Method)
	log.Println("r.Proto = ", r.Proto)
	log.Println("r.URL.Path = ", r.URL.Path)
	log.Println("r.URL.Scheme = ", r.URL.Scheme)
	log.Println("r.Form = ", r.Form)
	log.Println("r.Form[url_long] = ", r.Form["url_long"])
	for k, v := range r.Form {
		log.Println("key:", k)
		log.Println("val:", strings.Join(v, ""))
	}
	log.Println("r.ContentLength = ", r.ContentLength)
	body, _ := ioutil.ReadAll(r.Body)
	log.Println("r.Body = ", body)
	log.Println("r.Body = ", string(body))

	cpx := &HTTPUseProtoBuf.MsgCmplx{}
	err := proto.Unmarshal(body, cpx)
	if err != nil {
		log.Fatal("unmarshaling error:", err)
	}

	log.Println(cpx)
	log.Println()

	fmt.Fprintf(w, "Get cpx in success!")
}

func main() {
	log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile)

	http.HandleFunc("/", sayhelloName)
	http.HandleFunc("/jsonPostLogin", jsonPostLogin)
	http.HandleFunc("/protoPostRegister", protoPostRegister)
	http.HandleFunc("/protoPostArr", protoPostArr)
	http.HandleFunc("/protoPostWrap", protoPostWrap)
	http.HandleFunc("/protoPostCmplx", protoPostCmplx)

	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		log.Fatal("ListenAndServer:", err)
	}
}
